<?php

namespace App\Service\WorkOrder\Reject;

use App\Enums\BaseErrorCode;
use App\Enums\WorkOrder\MissionEnum;
use App\Enums\WorkOrder\OrderEnum;
use App\Exceptions\Custom\ResponseHttpException;
use App\Models\ChatGroup\ChatGroupUserModel;
use App\Models\Common\ResourcesModel;
use App\Models\FuYou\WorkOrderFuyouLogModel;
use App\Models\System\SystemNotifyCenterModel;
use App\Models\WorkOrder\WorkOrderApplyMainModel;
use App\Models\WorkOrder\WorkOrderMissionModel;
use App\Models\WorkOrder\WorkOrderOperateLogModel;
use App\Models\WorkOrder\WorkOrderRejectDetailModel;
use App\Models\WorkOrder\WorkOrderRejectModel;
use App\Remote\Rms\RmsUserRemote;
use App\Service\Common\SmsService;
use App\Service\FuYou\FuYouService;
use App\Service\System\SystemNotifyService;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Overtrue\EasySms\Exceptions\InvalidArgumentException;

class WorkOrderRejectService
{
    private ?WorkOrderApplyMainModel $applyMainModel = null;

    public function __construct(string $workOrderNo, ?WorkOrderApplyMainModel $workOrderApplyMainModel = null)
    {
        if ($workOrderNo) {
            $this->applyMainModel = WorkOrderApplyMainModel::query()->where('workOrderNo', $workOrderNo)->withoutGlobalScope('isDel')->first();
        }

        if ($workOrderApplyMainModel) {
            $this->applyMainModel = $workOrderApplyMainModel;
        }

        if (!$this->applyMainModel) {
            throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null, "不存在的工单号");
        }
    }

    /**
     * 是否可以发起驳回
     * @param int $currentUid
     * @return void
     */
    public function checkReject(int $currentUid): void
    {
        if (!in_array($this->applyMainModel->step, [
            MissionEnum::STEP_2,
            MissionEnum::STEP_4,
            MissionEnum::STEP_5,
            MissionEnum::STEP_7,
            MissionEnum::STEP_8
        ])) {
            throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null, "当前阶段无法发起驳回");
        }

        $mission = WorkOrderMissionModel::query()
                                        ->where('workOrderNo', $this->applyMainModel->workOrderNo)
                                        ->where('dealUid', $currentUid)
                                        ->where('missionStatus', MissionEnum::MISSION_STATUS_0)
                                        ->first();
        if (!$mission) {
            throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null, "您当前不是任务处理人，无法驳回");
        }

        $reject = WorkOrderRejectModel::query()
                                      ->where('workOrderNo', $this->applyMainModel->workOrderNo)
                                      ->where('createdByUid', $currentUid)
                                      ->where('status', WorkOrderRejectModel::STATUS_INIT)
                                      ->first();
        if ($reject) {
            throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null, "已存在您发起的驳回中的订单，无法再次发起");
        }
    }


    /**
     * 发起驳回
     * @param int $currentUid
     * @param array $content
     * @return void
     * @throws GuzzleException
     * @throws InvalidArgumentException
     */
    public function doReject(int $currentUid, array $content)
    {
        // 判断权限
        $this->checkReject($currentUid);

        $rejectReason = "";
        // 增加驳回记录
        DB::transaction(function () use ($content, &$rejectReason) {
            $applyContent = json_decode($this->applyMainModel->contentRel->content, true);

            $reject = (new WorkOrderRejectModel([
                'workOrderNo' => $this->applyMainModel->workOrderNo,
                'step'        => $this->applyMainModel->step,
                'status'      => WorkOrderRejectModel::STATUS_INIT,
            ]))->addData();

            $detailData = [];
            $resMsg     = "驳回信息: ";
            foreach ($content as $v) {
                $resource = ((array)ResourcesModel::getModuleBusinessResources(ResourcesModel::MODULE_TYPE_WORK_ORDER,
                        '',
                        $this->applyMainModel->contentRel->id, [$v['field']]))[$v['field']] ?? [];

//                if (!isset($applyContent[$v['field']]) && !$resource) {
//                    throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null, "当前工单不存在field:{$v['field']}");
//                }
                $resMsg       .= $v['fieldText'] . " ";
                $detailData[] = [
                    'workOrderNo'      => $this->applyMainModel->workOrderNo,
                    'rejectId'         => $reject->id,
                    'field'            => $v['field'],
                    'fieldText'        => $v['fieldText'],
                    'fieldValue'       => empty($resource) ?
                        (is_array($applyContent[$v['field']] ?? "") ? json_encode($applyContent[$v['field']]) : $applyContent[$v['field']] ?? "") :
                        json_encode($resource, JSON_UNESCAPED_UNICODE),
                    'reasonOptionText' => $v['reasonOptionText'],
                    'reasonText'       => $v['reasonText'],
                ];
                $rejectReason .= vsprintf(
                    "[%s] [%s] [%s] %s",
                    [$v['fieldText'], $v['reasonOptionText'], $v['reasonText'], PHP_EOL]
                );
            }

            WorkOrderRejectDetailModel::batchAddData(collect($detailData));

            $this->applyMainModel->saveChildStep(MissionEnum::CHILD_STEP_1);
            if ($this->applyMainModel->problemChildId == OrderEnum::PROBLEM_PID_5_CHILDREN_105) {//夸父收银进件2.0
                //增加富友驳回记录--驳回返回到第一步
                $fuYouService = new FuYouService();
                $fuYouService::addLog($this->applyMainModel->workOrderNo, $content, 400, $resMsg,
                    WorkOrderFuyouLogModel::DEFAULT_ADMIN_REJECT_STATUS, getRmsUserInfoByAuth()->id);
            }
        });

        //日志 - 驳回抢单
        WorkOrderOperateLogModel::generateOperateLog(
            $this->applyMainModel->workOrderNo,
            $this->applyMainModel->step,
            WorkOrderOperateLogModel::TYPE_12,
            request()->user()->username,
            request()->user()->id,
            $rejectReason
        );
        $this->doRejectHook();
    }

    /**
     * 驳回钩子
     *
     * @throws GuzzleException
     * @throws InvalidArgumentException
     */
    public function doRejectHook()
    {
        $fsMsgSend = function () {
            $pushUidMap = array_values(
                array_column(
                    (RmsUserRemote::getShopManagerUserByShopId([$this->applyMainModel->shopId])['lists'] ?? []),
                    "userId"
                )
            );

            SystemNotifyService::customerBatchPush(
                $pushUidMap,
                '您提交的工单有内容需要修改',
                "尊敬的夸父伙伴您好，您提交的工单（ID：{$this->applyMainModel->workOrderNo}）客服已处理回复相关信息，有内容需要修改，请登录夸父商家\"门店-问题反馈-反馈进度\"查看处理。",
                OrderEnum::getDetailUrl($this->applyMainModel),
                $this->applyMainModel->shopId,
                SystemNotifyCenterModel::NOTIFY_TYPE_5
            );
        };

        $smsMsgSend = function () {
            $rmsUser = RmsUserRemote::getRmsUserByIds([$this->applyMainModel->createdByUid]);
            if ($rmsUser) {
                //发送阿里云短信
                (new SmsService())->aliyunSend(
                    current($rmsUser)["mobile"],
                    config('sms.template.workOrderOpenFunctionReject'),
                    [
                        "WorkOrderNo" => $this->applyMainModel->workOrderNo,
                    ]
                );
            }
        };

        //飞书消息通知
        $fsMsgSend();
        //短信通知
        $smsMsgSend();
    }


// 驳回详情
    public
    function detailReject(): Collection
    {
        if ($this->applyMainModel->childStep != MissionEnum::CHILD_STEP_1) {
            return collect();
        }

        $rejectIds = WorkOrderRejectModel::query()
                                         ->where('workOrderNo', $this->applyMainModel->workOrderNo)
                                         ->where('status', WorkOrderRejectModel::STATUS_INIT)
                                         ->pluck('id');
        if (!$rejectIds->count()) {
            return collect();
        }

        // 重复的field取后来的
        $fields = [];
        return WorkOrderRejectDetailModel::query()
                                         ->whereIn('rejectId', $rejectIds)
                                         ->orderByDesc('id')
                                         ->get()
                                         ->filter(function ($item) use (&$fields) {
                                             if (!isset($fields[$item['field']])) {
                                                 $fields[$item['field']] = 1;
                                                 return true;
                                             }

                                             return false;
                                         })
                                         ->values();
    }

    // 解决驳回
    public function fixReject($uid): int
    {
        $lastRejectUserId = WorkOrderRejectModel::query()
                                                ->where('workOrderNo', $this->applyMainModel->workOrderNo)
                                                ->where('status', WorkOrderRejectModel::STATUS_INIT)
                                                ->value('createdByUid') ?? 0;

        $this->applyMainModel->saveChildStep(MissionEnum::CHILD_STEP_0);
        WorkOrderRejectModel::saveStatus($this->applyMainModel->workOrderNo, WorkOrderRejectModel::STATUS_OK);

        $this->applyMainModel->createdAt    = time();
        $this->applyMainModel->createdByUid = $uid;//提交人
        $this->applyMainModel->save();

        return $lastRejectUserId;
    }

    /**
     * 所有驳回详情
     * @param int $shopId
     * @param int $userId
     * @return array
     */
    public static function rejectDetails(int $shopId, int $userId): array
    {
        $lists = WorkOrderApplyMainModel::query()
                                        ->where('shopId', $shopId)
                                        ->where('status', OrderEnum::MAIN_STATUS_ING)
                                        ->where('childStep', MissionEnum::CHILD_STEP_1)
                                        ->orderBy('id')
                                        ->get();

        // 判断是否有群聊
        $chatGroupId = (int)ChatGroupUserModel::query()
            ->where('shopId', $shopId)
            ->where('userId', $userId)
            ->value('groupId');

        return [
            'count'     => $count = $lists->count(),
            "message"   => !$count ? "" : "您有{$count}条问题反馈待修改，请点击重新填写",
            'firstInfo' => !$count ? (object)[] : [
                'workOrderNo'    => $lists->first()->workOrderNo,
                'problemPid'     => $lists->first()->problemPid,
                'problemChildId' => $lists->first()->problemChildId,
            ],
            'chatGroupId' => $chatGroupId,
        ];
    }
}
